package cn.sciento.boot.api.customize;

import java.util.ArrayList;
import java.util.List;
import cn.sciento.boot.api.customize.commons.repository.ApiCustomizeRepository;
import cn.sciento.boot.api.customize.commons.repository.impl.DefaultApiCustomizeRepository;
import cn.sciento.boot.api.customize.config.CustomizeInitializeConfig;
import cn.sciento.boot.api.customize.config.CustomizeProperties;
import cn.sciento.boot.api.customize.generator.AbstractCodeGenerator;
import cn.sciento.boot.api.customize.generator.CodeGenerator;
import cn.sciento.boot.api.customize.generator.CompositeCodeGenerator;
import cn.sciento.boot.api.customize.generator.GroovyCodeGenerator;
import cn.sciento.boot.api.customize.generator.JavaCodeGenerator;
import cn.sciento.boot.api.customize.generator.UrlCodeGenerator;
import cn.sciento.boot.api.customize.helper.HttpRequestHelper;
import cn.sciento.boot.api.customize.helper.impl.DefaultHttpRequestHelper;
import cn.sciento.boot.api.customize.service.ApiCustomizeService;
import cn.sciento.boot.api.customize.service.ApiScanService;
import cn.sciento.boot.api.customize.service.impl.DefaultApiCustomizeService;
import cn.sciento.boot.api.customize.service.impl.DefaultApiScanService;
import cn.sciento.core.redis.RedisHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@ComponentScan({"cn.sciento.boot.api.customize.commons", "cn.sciento.boot.api.customize.controller", "cn.sciento.boot.api.customize.service", "cn.sciento.boot.api.customize.generator"})
@Configuration
@EnableConfigurationProperties({CustomizeProperties.class})
public class CustomizeAutoConfiguration {
  @Autowired
  private CustomizeProperties properties;
  
  @Bean
  @ConditionalOnClass(name = {"javassist.ClassPool"})
  @ConditionalOnMissingBean({ApiScanService.class})
  public ApiScanService scanService() {
    return (ApiScanService)new DefaultApiScanService();
  }
  
  @Bean
  @ConditionalOnMissingBean({ApiCustomizeRepository.class})
  public ApiCustomizeRepository customizeRepository(RedisHelper redisHelper) {
    return (ApiCustomizeRepository)new DefaultApiCustomizeRepository(redisHelper);
  }
  
  @Bean
  @ConditionalOnMissingBean({CodeGenerator.class})
  public CodeGenerator codeGenerator() {
    return (CodeGenerator)new CompositeCodeGenerator(buildCodeGenerator());
  }
  
  @Bean
  @ConditionalOnMissingBean({ApiCustomizeService.class})
  public ApiCustomizeService apiCustomizeService(ApiCustomizeRepository customizeRepository, CodeGenerator codeGenerator) {
    return (ApiCustomizeService)new DefaultApiCustomizeService(customizeRepository, codeGenerator);
  }
  
  @Bean
  public CustomizeInitializeConfig customizeInitializeConfig() {
    return new CustomizeInitializeConfig();
  }
  
  @Bean
  @ConditionalOnMissingBean({HttpRequestHelper.class})
  public HttpRequestHelper httpRequestHelper() {
    return (HttpRequestHelper)new DefaultHttpRequestHelper();
  }
  
  protected List<AbstractCodeGenerator> buildCodeGenerator() {
    List<AbstractCodeGenerator> codeGenerators = new ArrayList<>(8);
    codeGenerators.add(new JavaCodeGenerator(this.properties));
    codeGenerators.add(new UrlCodeGenerator());
    codeGenerators.add(new GroovyCodeGenerator());
    return codeGenerators;
  }
}
